Using AI to Write ChartIQ Integration Code
Large language models (LLMs) such as Anthropic Claude, OpenAI GPT-4, and Google Gemini can generate production-quality ChartIQ integration code when given the right documentation as context. This tutorial explains how to structure that workflow so that the AI produces reliable code — and how to catch and correct the errors that occur when it does not.
Note This tutorial is about using an AI to write ChartIQ integration code for you, not about using ChartIQ's AI Ready plugin to drive the chart at runtime. For runtime AI chart control, see the AI Ready Tutorial.
Important LLMs have a knowledge cutoff date and may not know the version of ChartIQ you are running. Always supply the relevant documentation page URLs or content in your prompt. Code generated without documentation context is likely to contain invented API signatures that will fail at runtime.
How the Workflow Works
The approach is straightforward: instead of writing boilerplate integration code from scratch, you describe what you want to an LLM, supply it with the relevant ChartIQ documentation pages, and let it produce a first draft. You then review the output critically, verify any API calls against the actual documentation, and iterate.
- Identify the relevant docs ↓
- Craft a precise prompt ↓
- Review & verify output ↓
- Test with
console.log↓ - Iterate
This workflow can accelerate integration work significantly. A quotefeed adapter that might take a day to write from scratch can be drafted in minutes. The developer's time shifts from writing boilerplate to reviewing, verifying, and refining — a much higher-value activity.
The Core Problem: AI Will Invent Things
LLMs are trained to produce plausible, fluent output. When they do not know the exact answer — a specific parameter name, a callback shape, an edge case behavior — they do not stop. They invent something that looks correct and continue. This is called hallucination, and it is the primary risk when using AI to write integration code.
In a real-world session building a ChartIQ FRED quotefeed, an AI produced this code without any warning:
// The AI invented this. params.period is a number (the rollup multiplier).
// It has no .timeUnit property. This fails silently at runtime.
function getFredFrequency(params) {
const timeUnit = params.period.timeUnit; // ← hallucinated
return PERIODICITY_MAP[timeUnit] || "d";
}
The AI had seen ChartIQ's setPeriodicity({ period, interval, timeUnit }) in its training data and assumed those same nested fields existed on the quotefeed params object. They do not. The quotefeed tutorial documents only params.interval and params.period as flat values. The AI never flagged the assumption — it presented invented code as fact.
This is not a one-off failure. It is the default behavior of every LLM when documentation context is absent or ambiguous. The sections below explain exactly how to prevent it.
Important — The Developer's Responsibility
AI-generated code must be treated as a first draft written by someone who has read the documentation but may have filled in gaps incorrectly. Every API call, every parameter name, and every callback shape in the generated code must be verified against the official ChartIQ documentation before the code is used. The AI cannot do this verification for you.
The Anti-Hallucination Prompt Block
The single most effective intervention is a set of explicit constraints added to every prompt. Copy this block and include it verbatim at the end of any ChartIQ coding request. It does not eliminate hallucination entirely, but it forces the AI to flag uncertainty rather than silently invent answers.
Anti-Hallucination Constraints — Copy Into Every Prompt
IMPORTANT CONSTRAINTS — follow these strictly:
1. Do not invent any API method names, parameter names, object shapes, or callback signatures. Only use names and structures that appear explicitly in the documentation I have provided or in the URLs I have given you.
2. If the documentation does not specify a particular field, parameter, or behavior, say so explicitly with the phrase "the documentation does not specify this" and stop. Do not guess. Do not use a plausible-sounding substitute.
3. If you find yourself inferring a parameter from a different part of the API (for example, assuming a quotefeed `params` field exists because it appears in a `setPeriodicity` call), stop, flag it clearly as an inference using the phrase "my inference, not from docs:", and ask me to verify it before continuing.
4. Do not present inferences as facts. Use explicit language: "the docs show...", "this is confirmed by...", or "I am inferring this because..." so I can tell what is grounded and what is not.
5. If you cannot complete a section of the code without inventing something, write a placeholder comment instead: `// TODO: verify correct field name — not found in provided documentation`
6. Before writing any code, list the documentation sources you are drawing from. If you have not been given documentation for a particular aspect of the integration, say so before writing code for that aspect.
7. Treat documentation sources by reliability tier. Prefer in this order: (a) official client library source code, (b) current API reference, (c) blog posts and changelogs. If you are drawing from a blog post or older article, say so explicitly and flag that it may be outdated. Never treat a post that describes a feature as "planned" or "coming soon" as confirmation that the feature exists today.
8. If two documentation sources conflict on the same point, do not silently pick one. Flag the conflict explicitly — state both values, identify which source you consider more authoritative and why, use the more current source in the code, and mark the affected line with a TODO comment for runtime verification.
Why Each Constraint Matters
| Constraint | What It Prevents |
|---|---|
| "Do not invent parameter names" | Prevents the AI from using field names like params.period.timeUnit that look correct but do not exist in the quotefeed interface |
| "Say 'the documentation does not specify this' and stop" | Forces the AI to expose its knowledge gaps rather than silently fill them with plausible-sounding code |
| "Flag inferences explicitly" | Separates confirmed API behavior from assumptions so you know exactly what to verify before running the code |
| "Do not present inferences as facts" | Prevents confident-sounding but incorrect explanations that waste hours of debugging time |
| TODO placeholder comments | Gives you a runnable file with clearly marked gaps rather than a complete-looking file with hidden errors |
| "List documentation sources before writing code" | If the AI cannot name a source for something, it has no basis for writing it — this makes that visible before the code is produced, not after |
| "Treat documentation sources by reliability tier" | Prevents the AI from treating a 2021 blog post describing a feature as "planned" as confirmation the feature exists today. The closer a source is to running code, the more trustworthy it is: client library source > current API reference > blog posts |
| "Flag conflicting sources explicitly" | When two documentation pages disagree on a parameter name or behavior, the AI will silently pick one. This constraint forces it to surface the conflict so you can verify at runtime rather than discover the bug in production |
Note — These Constraints Are Not Foolproof
Even with these constraints in place, an AI may still hallucinate in subtle ways. The constraints reduce frequency and make errors more visible — they do not eliminate them. Runtime verification with
console.log(params)and cross-checking against the licensed API reference remain essential steps. Additional failure modes discovered in practice: (1) the AI reads real documentation but the docs are stale — a feature described as "planned" may or may not have shipped; (2) two pages in the same documentation site can contradict each other, and the AI will silently pick one without flagging the conflict. Constraints 7 and 8 above address both of these.
Step 1 — Identify the Relevant Documentation
The quality of AI-generated code is directly proportional to the quality of documentation you provide. Before prompting, locate the specific ChartIQ documentation pages that describe the feature you want to implement.
For a quotefeed integration, the relevant pages are:
- Data Integration: Quotefeeds — defines
fetchInitialData,fetchUpdateData,fetchPaginationData, and thecbcallback shape - Understanding Periodicity and masterData — explains
params.interval,params.period, and howtimeUnitvalues map to data frequencies - The ChartIQ Format for Time-Series Data — defines the required
DT,Open,High,Low,Close,Volumefields - Cross-Origin Resource Sharing (CORS) — explains why direct browser-to-API calls are blocked and how to proxy them
Tip Many AI assistants support providing URLs directly in the prompt. If yours does, include the documentation URLs and ask the AI to read them before generating code. If it cannot access URLs, paste the relevant sections of text from the documentation into the prompt directly.
Step 2 — Craft a Precise Prompt
A vague prompt produces vague code. A precise prompt that specifies the data source, the ChartIQ interface being implemented, and the constraints of the integration will produce code you can actually use.
Prompt Structure
A well-structured prompt contains four parts:
- Context — what you are building and which library you are using
- Documentation reference — the specific pages the AI should use
- Task — exactly what code you want generated
- Constraints — things the AI must not invent or assume
Example: Quotefeed Prompt
The following prompt was used to generate a working FRED API quotefeed adapter for ChartIQ. It demonstrates how each of the four parts works in practice.
Prompt
I am building a ChartIQ integration that loads economic time-series data from the St. Louis Fed FRED API (https://fred.stlouisfed.org/docs/api/fred/) into a ChartIQ chart using the quotefeed pattern described at https://documentation.chartiq.com/tutorial-DataIntegrationQuoteFeeds.html.
Please read both documentation pages before writing any code.
Write a JavaScript quotefeed object with `fetchInitialData`, `fetchUpdateData`, and `fetchPaginationData` methods that:
1. Uses the symbol passed to the fetch functions as the FRED series ID
2. Maps ChartIQ's `params.interval` to a FRED frequency parameter (daily, weekly, or monthly only — return an error for unsupported intervals)
3. Transforms FRED observations into ChartIQ's OHLC format (set Open, High, Low, and Close all equal to the FRED scalar value)
4. Handles FRED's missing data indicator (a literal "." string)
5. Returns `moreAvailable: false` since FRED returns the full requested range in one response
Do not invent any API method signatures or parameters not shown in the documentation. If you are uncertain about a parameter name, say so explicitly rather than guessing.
What Makes This Prompt Effective
| Prompt Element | Why It Matters |
|---|---|
| Documentation URLs provided upfront | Grounds the AI in actual API signatures rather than training data that may be outdated |
| "Read both pages before writing code" | Forces the AI to process the documentation before generating output |
| Numbered requirements | Gives the AI a checklist to work through, reducing omissions |
| Explicit constraint on inventing parameters | The most important constraint. Without it, the AI will silently fill gaps with plausible-but-wrong parameter names such as params.period.timeUnit |
| Error behavior specified | Tells the AI what to do at the edges, not just the happy path |
Step 3 — Review the Output Critically
AI-generated code requires the same review you would give code from a junior developer who is unfamiliar with your codebase. Do not assume correctness. Specifically, check for:
Invented API Signatures
The most common failure mode. The AI will produce code that looks correct but references method parameters or object shapes that do not exist in the ChartIQ library.
For example, a prompt without the constraint above produced this in the
getFredFrequency function:
// WRONG — params.period is a number (the rollup multiplier).
// It does not have a .timeUnit property.
const timeUnit = params.period.timeUnit;
The correct access, as shown in the quotefeed tutorial example code, is:
// CORRECT — params.interval is the field documented in the quotefeed tutorial.
const interval = params.interval;
Important If the AI uses a parameter name you do not recognize, verify it against the documentation before proceeding. The quotefeed API reference and the quotefeed tutorial are the authoritative sources. If the docs are ambiguous, use
console.log(params)inside a fetch function at runtime — this is definitive.
Missing Error Handling
AI-generated code frequently handles only the happy path. Check that the output handles:
- Network errors (the
fetchcall itself throws) - API error responses (FRED returns
{ error_code, error_message }in the JSON body) - Empty observation arrays (a valid FRED response with no data points in the requested range)
- Unsupported periodicities (a chart user switching to a 5-minute interval on an economic series)
CORS Assumptions
AI models often generate code that calls third-party APIs directly from the browser. This will fail with a CORS error in development. See the CORS tutorial for the correct approach: route requests through a server-side proxy, which also keeps your API key out of client-side JavaScript.
For local development, a minimal Node proxy handles this in about 10 lines:
// fred-proxy.js — run with: node fred-proxy.js
const express = require("express");
const fetch = require("node-fetch");
const app = express();
const FRED_API_KEY = "YOUR_KEY_HERE"; // injected server-side; never in client code
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
next();
});
app.get("/fred", async (req, res) => {
const params = new URLSearchParams(req.query);
params.set("api_key", FRED_API_KEY);
params.set("file_type", "json");
const data = await fetch(
`https://api.stlouisfed.org/fred/series/observations?${params}`
);
res.json(await data.json());
});
app.listen(3001, () => console.log("Proxy running on http://localhost:3001"));
Step 4 — Verify at Runtime with console.log
Documentation gaps — parameters described but not fully specified — cannot be resolved by reading alone. Logging the actual runtime value is the fastest resolution.
The quotefeed tutorial documents params.interval and params.period but does not specify every field on the params object. To see everything ChartIQ actually passes, add one line to your fetchInitialData:
fetchInitialData: function (symbol, suggestedStartDate, endDate, params, cb) {
console.log("ChartIQ params:", params); // examine this in DevTools before proceeding
// ... rest of your implementation
},
Load your chart, open the browser DevTools console, and the full params object will appear on the first data request. This tells you definitively what field names to use in your frequency mapping logic.
Tip Once you have logged params, copy the output and paste it back into the AI prompt: "Here is the actual params object ChartIQ passes: [paste]. Update the getFredFrequency function to use the correct field." This closes the documentation gap and produces corrected code immediately.
Step 5 — Iterating with the AI
Treat the AI as a collaborative development partner, not an oracle. The interaction should be a dialogue: you provide documentation, the AI generates a draft, you identify specific problems, the AI fixes them.
Effective Iteration Prompts
After reviewing the initial output, frame corrections precisely. Vague correction prompts produce vague fixes.
| Instead of | Say |
|---|---|
| "This doesn't work" | "The getFredFrequency function accesses params.period.timeUnit but the quotefeed tutorial shows params.interval and params.period as flat fields, not nested. Fix the frequency mapping to use params.interval." |
| "Add error handling" | "The fetch function does not handle the case where the FRED API returns { error_code, error_message } in the JSON body. Add a check for this before calling transformObservations and pass the error string to cb." |
| "Fix the CORS issue" | "The quotefeed calls api.stlouisfed.org directly from the browser. Change FRED_BASE_URL to point to http://localhost:3001/fred and remove the api_key from the client-side URLSearchParams since the proxy injects it." |
When to Stop Iterating with AI
If after two or three attempts the AI continues to produce incorrect output for the same issue, the documentation it was given likely does not contain enough information to resolve it. At that point:
- Check the licensed API reference (
quotefeed.htmlin your SDK package) - Check the source files that ship with the library (
quoteFeedSimulator.js) - Use
console.logat runtime to gather the missing facts, then re-prompt - Contact ChartIQ support at support@chartiq.com
What AI Does Well vs. What It Gets Wrong
| AI Does Well | AI Gets Wrong Without Good Docs |
|---|---|
| Boilerplate structure (the three fetch functions, the IIFE pattern, the callback shape) | Exact parameter names on the params object |
| Data transformation logic (parsing dates, mapping scalars to OHLC) | Nested vs. flat field access (e.g. params.period.timeUnit vs. params.interval) |
| Error handling patterns | Which ChartIQ API calls display errors visually vs. silently |
| URLSearchParams construction and fetch/async patterns | CORS behavior — it will often generate direct browser-to-API calls |
| Code organization and comments | Behavior of moreAvailable flag edge cases |
| Finding relevant documentation pages | Stale documentation — a blog post describing a feature as "planned" may be years old. The AI treats it as current fact unless explicitly told otherwise |
| Applying a single authoritative source consistently | Conflicting documentation — when two pages in the same docs site disagree (e.g. one says adjusted=true, another says unadjusted=false), the AI picks one silently without flagging the conflict |
| Writing correct success-path logic | Incomplete response status handling — assuming only one valid success value (e.g. status === "OK") when the API can return multiple valid statuses such as "DELAYED" for lower-tier plans |
Sample: Complete FRED Quotefeed Prompt
The following is the full prompt that produced the FRED quotefeed adapter referenced throughout this tutorial. Copy, adapt, and extend it for your own integrations.
Full Prompt — FRED Quotefeed (with anti-hallucination constraints)
I am building a JavaScript quotefeed for ChartIQ that loads economic data from the St. Louis Fed FRED API.
Please read these two documentation pages before writing any code:
1. ChartIQ quotefeed tutorial: https://documentation.chartiq.com/tutorial-DataIntegrationQuoteFeeds.html
2. FRED series observations API: https://fred.stlouisfed.org/docs/api/fred/series_observations.html
Before writing any code, confirm which documentation you are drawing from for each section of the implementation.
Requirements:
- Implement `fetchInitialData`, `fetchUpdateData`, and `fetchPaginationData` exactly as described in the ChartIQ quotefeed tutorial
- The symbol passed to each fetch function is the FRED series ID (e.g. "UNRATE", "CPIAUCSL")
- Use `params.interval` (documented in the quotefeed tutorial) to determine the FRED frequency parameter. Support only "day" → "d", "week" → "w", "month" → "m". Return `cb({ error: "No data available for this periodicity..." })` for all other values without making any network request
- Parse FRED date strings ("YYYY-MM-DD") to UTC midnight JavaScript Date objects
- Map each FRED observation value to Open, High, Low, and Close (all equal) to satisfy ChartIQ's OHLC format. Set Volume to 0
- Skip FRED observations where value is the string "." (missing data indicator)
- Return `moreAvailable: false` in all callbacks
- The API key must not appear in client-side code. Use a configurable FRED_BASE_URL that defaults to a local proxy URL
IMPORTANT CONSTRAINTS — follow these strictly:
1. Do not invent any API method names, parameter names, object shapes, or callback signatures. Only use names and structures that appear explicitly in the documentation I have provided.
2. If the documentation does not specify a particular field, parameter, or behavior, say so explicitly with the phrase "the documentation does not specify this" and stop. Do not guess. Do not use a plausible-sounding substitute.
3. If you find yourself inferring a parameter from a different part of the API (for example, assuming a quotefeed `params` field exists because it appears in a `setPeriodicity` call elsewhere in the docs), stop, flag it clearly as "my inference, not from docs:" and ask me to verify before continuing.
4. Do not present inferences as facts. Use explicit language: "the docs show...", "this is confirmed by...", or "I am inferring this because..." so I can tell at a glance what is grounded in documentation and what is not.
5. If you cannot complete a section without inventing something, write a placeholder comment instead: // TODO: verify correct field name — not found in provided documentation
6. Include inline comments on every non-obvious decision, and note which documentation source justifies each decision.
7. Treat documentation sources by reliability tier. Prefer: (a) official client library source code, (b) current API reference, (c) blog posts and changelogs. If drawing from a blog post or older article, say so explicitly and flag it may be outdated. Never treat a feature described as "planned" or "coming soon" as confirmed to exist today.
8. If two documentation sources conflict on the same point, flag the conflict explicitly. State both values, identify which source is more authoritative, use the more current source in the code, and mark the affected line with a TODO comment.
Next Steps
- Data Integration: Quotefeeds — the primary reference for the quotefeed interface
- AI Ready Tutorial — using AI to drive the chart at runtime via the CLI plugin
- Cross-Origin Resource Sharing (CORS) — required reading before deploying any quotefeed that calls a third-party API
- Reference Data — for integrating supplemental economic data as overlays on a primary price chart
- ChartIQ Quotefeeds on GitHub — prebuilt quotefeeds for reference and as starting points for AI prompting
